﻿' ----------------------------------------------------------------------------------
' Microsoft Developer & Platform Evangelism
' 
' Copyright (c) Microsoft Corporation. All rights reserved.
' 
' THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
' EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
' OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ----------------------------------------------------------------------------------
' The example companies, organizations, products, domain names,
' e-mail addresses, logos, people, places, and events depicted
' herein are fictitious.  No association with any real company,
' organization, product, domain name, email address, logo, person,
' places, or events is intended or should be inferred.
' ----------------------------------------------------------------------------------

Imports Microsoft.Samples.WindowsPhoneCloud.StorageClient.Credentials
Imports System.Windows.Threading
Imports System.Globalization

Namespace ViewModel
    Public Class LoginPageViewModel
        Inherits BaseViewModel
        Private ReadOnly cloudClientFactory As ICloudClientFactory
        Private ReadOnly dispatcher As Dispatcher
#If ACS Then
		Private _sslCertificateUri As Uri
		Private _message As String
		Private _isBusy As Boolean

		Public Sub New()
			Me.New(App.CloudClientFactory, TryCast(Application.Current.Resources("SSLCertificateUrl"), String), Deployment.Current.Dispatcher)
		End Sub

		Public Sub New(ByVal cloudClientFactory As ICloudClientFactory, ByVal sslCertificateUrl As String, ByVal dispatcher As Dispatcher)
			Me.cloudClientFactory = cloudClientFactory
			Me.dispatcher = dispatcher

			Dim uri As Uri = Nothing
			Uri.TryCreate(sslCertificateUrl, UriKind.Absolute, uri)
			Me._sslCertificateUri = uri
		End Sub

		Public Property Message() As String
			Get
				Return Me._message
			End Get

			Set(ByVal value As String)
				If Me._message <> value Then
					Me._message = value
					Me.NotifyPropertyChanged("Message")
				End If
			End Set
		End Property

		Public Property IsBusy() As Boolean
			Get
				Return Me._isBusy
			End Get

			Set(ByVal value As Boolean)
				If Me._isBusy <> value Then
					Me._isBusy = value
					Me.NotifyPropertyChanged("IsBusy")
				End If
			End Set
		End Property

		Public ReadOnly Property IsSslCertificateLinkVisible() As Boolean
			Get
				Return Me.SslCertificateUri IsNot Nothing
			End Get
		End Property

		Public Property SslCertificateUri() As Uri
			Get
				Return Me._sslCertificateUri
			End Get

			Set(ByVal value As Uri)
				If Me._sslCertificateUri <> value Then
					Me._sslCertificateUri = value
					Me.NotifyPropertyChanged("SslCertificateUri")
					Me.NotifyPropertyChanged("IsSslCertificateLinkVisisble")
				End If
			End Set
		End Property

        Public Sub HandleRequestSecurityTokenResponseCompleted(ByVal sender As Object, ByVal e As SL.Phone.Federation.Controls.RequestSecurityTokenResponseCompletedEventArgs, ByVal registeredCallback As Action, ByVal notRegisteredCallback As Action, ByVal errorCallback As Action(Of String))
            If e.Error Is Nothing Then
                ' check if user is already registered for this application
                Me.dispatcher.BeginInvoke(Sub()
                                              Try
                                                  Me.IsBusy = True
                                                  Me.Message = "Checking user registration..."
                                                  Me.cloudClientFactory.ResolveRegistrationClient().CheckUserRegistration(Sub(args)
                                                                                                                              Me.dispatcher.BeginInvoke(Sub()
                                                                                                                                                            Me.IsBusy = False
                                                                                                                                                            Me.Message = "User registered"
                                                                                                                                                            registeredCallback()
                                                                                                                                                        End Sub)
                                                                                                                          End Sub,
                                                                                                                          Sub(args)
                                                                                                                              Me.dispatcher.BeginInvoke(Sub()
                                                                                                                                                            Me.IsBusy = False
                                                                                                                                                            Me.Message = "User not registered"
                                                                                                                                                            notRegisteredCallback()
                                                                                                                                                        End Sub)
                                                                                                                          End Sub,
                                                                                                                          Sub(args)
                                                                                                                              Me.dispatcher.BeginInvoke(Sub()
                                                                                                                                                            Me.cloudClientFactory.CleanAuthenticationToken()
                                                                                                                                                            Me.IsBusy = False
                                                                                                                                                            Me.Message = "Error"
                                                                                                                                                            errorCallback(String.Empty)
                                                                                                                                                        End Sub)
                                                                                                                          End Sub)
                                              Catch ex As Exception
                                                  Me.IsBusy = False
                                                  Me.Message = "Server Configuration Error"
                                                  errorCallback("Theres is a problem with the server configuration. Please, contact the application vendor. Exit the application and try again later.")
                                              End Try
                                          End Sub)
            End If
        End Sub


#Else
        Private ReadOnly authenticationClient As IAuthenticationClient
        Private sslCertificateUriValue As Uri
        Private messageValue As String
        Private userNameValue As String
        Private passwordValue As String
        Private rememberMeValue As Boolean = True
        Private credentialsErrorValue As Boolean
        Private isBusyValue As Boolean

        Public Sub New()
            Me.New(App.CloudClientFactory, TryCast(Application.Current.Resources("SSLCertificateUrl"), String), Deployment.Current.Dispatcher)
        End Sub

        Public Sub New(ByVal cloudClientFactory As ICloudClientFactory, ByVal sslCertificateUrl As String, ByVal dispatcher As Dispatcher)
            Me.cloudClientFactory = cloudClientFactory
            Me.authenticationClient = Me.cloudClientFactory.ResolveAuthenticationClient()
            Me.dispatcher = dispatcher

            Dim uri As Uri = Nothing
            uri.TryCreate(sslCertificateUrl, UriKind.Absolute, uri)
            Me.sslCertificateUriValue = uri
        End Sub

        Public Property UserName() As String
            Get
                Return Me.userNameValue
            End Get

            Set(ByVal value As String)
                If Me.userNameValue <> value Then
                    Me.userNameValue = value
                    Me.NotifyPropertyChanged("UserName")
                    Me.NotifyPropertyChanged("IsLoginEnabled")
                    Me.CredentialsError = False
                End If
            End Set
        End Property

        Public Property Password() As String
            Get
                Return Me.passwordValue
            End Get

            Set(ByVal value As String)
                If Me.passwordValue <> value Then
                    Me.passwordValue = value
                    Me.NotifyPropertyChanged("Password")
                    Me.NotifyPropertyChanged("IsLoginEnabled")
                    Me.CredentialsError = False
                End If
            End Set
        End Property

        Public Property RememberMe() As Boolean
            Get
                Return Me.rememberMeValue
            End Get

            Set(ByVal value As Boolean)
                If Me.rememberMeValue <> value Then
                    Me.rememberMeValue = value
                    Me.NotifyPropertyChanged("RememberMe")
                End If
            End Set
        End Property

        Public Property Message() As String
            Get
                Return Me.messageValue
            End Get

            Set(ByVal value As String)
                If Me.messageValue <> value Then
                    Me.messageValue = value
                    Me.NotifyPropertyChanged("Message")
                End If
            End Set
        End Property

        Public ReadOnly Property IsSslCertificateLinkVisisble() As Boolean
            Get
                Return Me.SslCertificateUri IsNot Nothing
            End Get
        End Property

        Public Property SslCertificateUri() As Uri
            Get
                Return Me.sslCertificateUriValue
            End Get

            Set(ByVal value As Uri)
                If Me.sslCertificateUriValue <> value Then
                    Me.sslCertificateUriValue = value
                    Me.NotifyPropertyChanged("SslCertificateUri")
                    Me.NotifyPropertyChanged("IsSslCertificateLinkVisisble")
                End If
            End Set
        End Property

        Public Property CredentialsError() As Boolean
            Get
                Return Me.credentialsErrorValue
            End Get

            Set(ByVal value As Boolean)
                If Me.credentialsErrorValue <> value Then
                    Me.credentialsErrorValue = value
                    Me.NotifyPropertyChanged("CredentialsError")
                End If
            End Set
        End Property

        Public Property IsBusy() As Boolean
            Get
                Return Me.isBusyValue
            End Get

            Set(ByVal value As Boolean)
                If Me.isBusyValue <> value Then
                    Me.isBusyValue = value
                    Me.NotifyPropertyChanged("IsBusy")
                End If
            End Set
        End Property

        Public ReadOnly Property IsLoginEnabled() As Boolean
            Get
                Return (Not String.IsNullOrEmpty(Me.UserName)) AndAlso Not String.IsNullOrEmpty(Me.Password)
            End Get
        End Property

        Public Sub Login(ByVal successCallback As Action, ByVal exceptionCallback As Action(Of String))
            Me.CredentialsError = False
            Me.IsBusy = True
            Me.Message = "Logging in..."
            Me.authenticationClient.Login(
                Me.UserName,
                Me.Password,
                Sub(args)
                    Me.cloudClientFactory.SetAuthenticationToken(args.AuthenticationToken, Me.RememberMe)
                    Me.dispatcher.BeginInvoke(
                        Sub()
                            Me.CredentialsError = False
                            Me.IsBusy = False
                            ' Continue flow.
                            successCallback()
                        End Sub)
                End Sub,
                Sub(args)
                    Me.dispatcher.BeginInvoke(
                        Sub()
                            Me.IsBusy = False
                            If args.WrongCredentials Then
                                Me.CredentialsError = True
                            Else
                                Me.CredentialsError = False
                                Dim errorMessage = String.Format(System.Globalization.CultureInfo.InvariantCulture, "Error in log in. Please try again later." & vbLf & "{0} {1}", args.Exception.Message, If(args.Exception.StatusCode = System.Net.HttpStatusCode.NotFound, "Please, make sure to install the SSL certificate in the phone.", String.Empty))
                                exceptionCallback(errorMessage)
                            End If
                        End Sub)
                End Sub)
        End Sub
#End If
    End Class
End Namespace